#include <fstream>
#include <iostream>
#include <iterator>
#include <numeric>
#include <stack>
#include <string>

int count_lead(const std::string& line) {
  int lead{0};
  for (auto i{line.cbegin()}; i != line.cend(); i++) {
    if (*i == ' ') {
      lead++;
    } else {
      return lead;
    }
  }
  return lead;
}

bool in_parentheses(const std::string& line) {
  static int comment{0};
  static int parentheses{0};
  static int brackets{0};
  static int square{0};
  bool res;
  if (comment < 0 || parentheses < 0 || brackets < 0 || square < 0) {
    throw "Too many '*/' or ')' or '}' or ']'";
  }
  if (comment == 0 && parentheses == 0 && brackets == 0 && square == 0) {
    res = false;
  } else {
    res = true;
  }
  auto i{line.cbegin()};
  while (i != line.cend()) {
    if (comment == 0) {
      switch (*i) {
      case '(':
        parentheses++;
        break;
      case ')':
        parentheses--;
        break;
      case '{':
        brackets++;
        break;
      case '}':
        brackets--;
        break;
      case '[':
        square++;
        break;
      case ']':
        square--;
        break;
      }
    }
    switch (*i) {
    case '/':
      if (i + 1 != line.cend() && *(i + 1) == '*') {
        comment++;
        i++;
      }
      break;
    case '*':
      if (i + 1 != line.cend() && *(i + 1) == '/') {
        comment--;
        i++;
      }
      break;
    }
    i++;
  }
  return res;
}

void process_line(const std::string& line, const bool& content=true) {
  static std::stack<int> deltas{};
  static int last{0};
  if (in_parentheses(line)) {
    std::cout << line << std::endl;
    return;
  }
  const int current{count_lead(line)};
  if (content && (current == line.size())) {
    std::cout << line << std::endl;
    return; // 不管空行    
  }
  
  const int delta{current - last};
  if (delta > 0) {
    deltas.push(delta);
    std::cout << std::string(last, ' ') << "{" << std::endl;
  } else if (delta == 0) {
  } else {
    int to_close{deltas.top()};
    int close_num{0};
    
    while (true)
    {
      deltas.pop();
      close_num += 1;
      if (to_close == -delta) {
        std::cout << std::string(current, ' ') << std::string(close_num, '}') << std::endl;
        break;
      }
      else if (to_close + delta < 0) { //delta还可能关闭更多
        to_close = to_close + deltas.top();
        continue;
      }
      else {
        throw "Changes in indents did not match!";
      }
    }
  }
  if (content) std::cout << line << std::endl;
  last = current;
}

int main(int argc, char **argv) {
  if (argc != 2) {
    std::cerr << "Usage: Culer [file name]" << std::endl;
    return 1;
  }
  char *&filename = argv[1];
  std::ifstream istrm(filename, std::ios::in);
  if (!istrm.is_open()) {
    std::cerr << "Failed to open " << filename << std::endl;
    return 1;
  }
  std::string line;
  try {
    std::string emp{""};
    process_line(emp, false);
    while (getline(istrm, line)) {
      process_line(line);
    }
    process_line(emp, false);
    return 0;
  } catch (char const *msg) {
    std::cerr << msg << std::endl;
  }
}
